home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pcmagazi / utility / chain / chain.asm next >
Assembly Source File  |  1987-11-17  |  12KB  |  262 lines

  1. DATA    SEGMENT WORD PUBLIC
  2.  
  3.         EXTRN   PrefixSeg:WORD
  4.         EXTRN   SaveInt00:DWORD
  5.         EXTRN   SaveInt02:DWORD
  6.         EXTRN   SaveInt23:DWORD
  7.         EXTRN   SaveInt24:DWORD
  8.         EXTRN   SaveInt75:DWORD
  9.  
  10. DATA    ENDS
  11.  
  12. CODE    SEGMENT BYTE PUBLIC
  13.  
  14.         ASSUME  CS:Code,DS:Data
  15.  
  16.         PUBLIC  Chain4
  17.  
  18. ;This generates a bunch of NOPs in object
  19. ;CodeLen = offset Dummy-offset CodeToRelocate    ;Length of code in PSP
  20. ;MaxCmdLen = 07Eh-CodeLen                        ;Maximum length of command line
  21.  
  22. ;These values must be exact
  23. ;They'll need changing if anything after label CodeToRelocate changes
  24. CodeLen         EQU     01Fh
  25. MaxCmdLen       EQU     05Fh
  26.  
  27. ;**************************************************************** Chain4
  28. ; procedure Chain4(Path, CmdLine : String);
  29. ;   Turbo 4 equivalent of chaining
  30.  
  31. ;Parameters
  32. PathArg         EQU     DWORD PTR [BP+10]
  33. CmdLine         EQU     DWORD PTR [BP+6]
  34.  
  35. ;Local variables
  36. CsInit          EQU     WORD PTR [BP-30+16h]    ;Fields within EXE header
  37. IpInit          EQU     WORD PTR [BP-30+14h]
  38. StackPtr        EQU     WORD PTR [BP-30+10h]
  39. StackSeg        EQU     WORD PTR [BP-30+0Eh]
  40. EXEHeader       EQU     WORD PTR [BP-30]        ;EXE header from file
  41. Path            EQU     BYTE PTR [BP-94]        ;ASCIIZ path string
  42.  
  43. Chain4  PROC    FAR
  44.  
  45.         PUSH    BP
  46.         MOV     BP,SP                           ;Set up stack frame
  47.         SUB     SP,94                           ;Make space for locals
  48.  
  49. ;Validate pathname and convert to ASCIIZ
  50.         PUSH    DS                              ;Save DS for later
  51.         PUSH    SS
  52.         POP     ES                              ;ES = SS
  53.         LEA     DI,Path                         ;ES:DI => ASCIIZ path
  54.         MOV     BX,DI                           ;Save offset of ASCIIZ
  55.         LDS     SI,PathArg                      ;DS:SI => file path in Turbo string
  56.         ASSUME  DS:nothing
  57.         CLD                                     ;Forward
  58.         LODSB                                   ;Get length byte
  59.         CMP     AL,63                           ;Longer than 63 characters?
  60.         JB      StoreASCIIZ
  61.         MOV     AL,63                           ;Truncate it
  62. StoreASCIIZ:
  63.         MOV     CL,AL                           ;CX = length
  64.         XOR     CH,CH
  65.         REP     MOVSB                           ;Copy to local Path
  66.         XOR     AL,AL                           ;Make ASCIIZ
  67.         STOSB
  68.  
  69. ;Assure file exists
  70.         PUSH    SS
  71.         POP     DS                              ;DS = SS
  72.         MOV     DX,BX                           ;DS:DX => ASCIIZ path
  73.         MOV     AX,3D00h                        ;Open file read-only
  74.         INT     21h
  75.         JNC     FileFound                       ;OK, file was found
  76.  
  77. Error:  POP     DS                              ;Restore DS
  78.         ASSUME  DS:Data
  79. Error1: MOV     SP,BP                           ;Return with error code in AX
  80.         POP     BP                              ;Restore BP
  81.         RET     8                               ;Remove parameters from stack
  82.  
  83. ;Read header and close file
  84. FileFound:
  85.         MOV     BX,AX                           ;BX = file handle
  86.         LEA     DX,ExeHeader                    ;DS:DX => ExeHeader
  87.         MOV     CX,28                           ;Read 28 bytes
  88.         MOV     AH,3Fh                          ;DOS read file
  89.         INT     21h
  90.         JC      Error                           ;Error if carry set
  91.         CMP     AX,CX
  92.         MOV     AX,30                           ;Prepare for Read Fault error
  93.         JNE     Error                           ;Error if 28 bytes not read
  94.         MOV     AH,3Eh                          ;Close file
  95.         INT     21h
  96.         JC      Error                           ;Error if carry set
  97.  
  98. ;Allocate all available memory to this process
  99.         POP     DS                              ;Restore DS
  100.         ASSUME  DS:Data
  101.         MOV     ES,PrefixSeg                    ;Main program segment
  102.         MOV     AH,4Ah                          ;Setblock
  103.         MOV     BX,0FFFFh                       ;Ask for everything
  104.         INT     21h
  105.         MOV     AH,4Ah                          ;Ask again for what we can get
  106.         INT     21h
  107.         JC      Error1                          ;Error if carry set now
  108.  
  109. ;Prepare to move stack to top of memory
  110.         MOV     AX,ES                           ;Base of program
  111.         ADD     AX,BX                           ;Add all available paragraphs
  112.         SUB     AX,1000h                        ;Room for full segment
  113.         MOV     CS:TmpSS,AX                     ;Store temporary SS
  114.  
  115. ;Close secondary file handles (don't touch StdIn,StdOut,StdErr)
  116.         MOV     BX,3                            ;Start with handle 3
  117.         MOV     CX,17                           ;17 handles max
  118. NextHandle:
  119.         MOV     AH,3Eh                          ;DOS close file
  120.         INT     21h
  121.         INC     BX                              ;Ignore errors
  122.         LOOP    NextHandle
  123.  
  124. ;Restore interrupt vectors taken over by SYSTEM library
  125.         MOV     CX,DS                           ;Save DS
  126.         MOV     AX,2500h                        ;Restore INT 00
  127.         LDS     DX,SaveInt00                    ;Get saved vector
  128.         ASSUME  DS:Nothing
  129.         INT     21h
  130.  
  131.         MOV     DS,CX                           ;Restore DS
  132.         ASSUME  DS:Data
  133.         MOV     AL,02h                          ;Restore INT 02
  134.         LDS     DX,SaveInt02                    ;Get saved vector
  135.         ASSUME  DS:Nothing
  136.         INT     21h
  137.  
  138.         MOV     DS,CX                           ;Restore DS
  139.         ASSUME  DS:Data
  140.         MOV     AL,23h                          ;Restore INT 23
  141.         LDS     DX,SaveInt23                    ;Get saved vector
  142.         ASSUME  DS:Nothing
  143.         INT     21h
  144.  
  145.         MOV     DS,CX                           ;Restore DS
  146.         ASSUME  DS:Data
  147.         MOV     AL,24h                          ;Restore INT 24
  148.         LDS     DX,SaveInt24                    ;Get saved vector
  149.         ASSUME  DS:Nothing
  150.         INT     21h
  151.  
  152.         MOV     DS,CX                           ;Restore DS
  153.         ASSUME  DS:Data
  154.         MOV     AL,75h                          ;Restore INT 75
  155.         LDS     DX,SaveInt75                    ;Get saved vector
  156.         ASSUME  DS:Nothing
  157.         INT     21h
  158.  
  159. ;Set up command line for chained program
  160.         LDS     SI,CmdLine                      ;DS:SI points to command line
  161.         MOV     DI,80h                          ;ES:DI => command line in PSP
  162.         LODSB                                   ;Get length byte
  163.         CMP     AL,MaxCmdLen                    ;Is is too long?
  164.         JB      StoreCmdLine                    ;No, don't truncate
  165.         MOV     AL,MaxCmdLen                    ;Truncate
  166. StoreCmdLine:
  167.         STOSB                                   ;Store length byte
  168.         MOV     BX,DI                           ;Save start of command line
  169.         MOV     CL,AL
  170.         XOR     CH,CH
  171.         REP     MOVSB                           ;Copy parameter to command line
  172.         MOV     AL,0Dh                          ;Terminate with <Enter>
  173.         STOSB
  174.  
  175. ;Initialize FCB's for new program
  176.         PUSH    ES
  177.         POP     DS                              ;DS = ES
  178.         MOV     SI,BX                           ;DS:SI => command line to parse
  179.         MOV     DI,005Ch                        ;ES:DI => FCB1
  180.         MOV     AX,2901h                        ;Init FCB1
  181.         INT     21h
  182.         MOV     DI,006Ch                        ;ES:DI => FCB2
  183.         MOV     AX,2901h                        ;Init FCB2
  184.         INT     21h
  185.  
  186. ;Save initialization data for new program
  187.         MOV     BX,ES                           ;Store prefix seg in BX
  188.         MOV     CS:NewCS,BX                     ;Assume COM file
  189.         MOV     CS:NewSS,BX
  190.         ADD     BX,10h                          ;BX = base segment
  191.         CMP     ExeHeader,5A4Dh                 ;Is it EXE format?
  192.         JNE     MoveCode                        ;No, COM file already initialized
  193.         MOV     AX,CsInit                       ;Get initial CS from EXE header,
  194.         ADD     AX,BX                           ;   relocate segment,
  195.         MOV     CS:NewCS,AX                     ;   write to code in PSP
  196.         MOV     AX,IpInit                       ;Initial IP
  197.         MOV     CS:NewIP,AX
  198.         MOV     AX,StackSeg                     ;Initial SS
  199.         ADD     AX,BX
  200.         MOV     CS:NewSS,AX
  201.         MOV     AX,StackPtr                     ;Initial SP
  202.         MOV     CS:NewSP,AX
  203.  
  204. ;Move code into PSP
  205. MoveCode:
  206.         MOV     CX,CodeLen                      ;Bytes to move
  207.         MOV     DI,100h                         ;DI => end of new code
  208.         SUB     DI,CX                           ;ES:DI => destination of new code
  209.         MOV     CS:TmpIP,DI                     ;Store address to jump to
  210.         MOV     CS:TmpCS,ES
  211.         PUSH    CS
  212.         POP     DS                              ;DS = CS
  213.         MOV     SI,offset CodeToRelocate        ;DS:SI => code to relocate
  214.         REP     MOVSB                           ;Copy the code to PSP
  215.  
  216. ;Prepare for EXEC call
  217.         MOV     AX,BX                           ;AX = Base segment
  218.         STOSW
  219.         STOSW                                   ;Initialize EXEC block
  220.         PUSH    SS
  221.         POP     DS                              ;DS = SS
  222.         LEA     DX,Path                         ;DS:DX => Path of file
  223.         MOV     BX,100h                         ;ES:BX => EXEC block
  224.         MOV     AX,4B03H                        ;Load Overlay
  225.         CLI
  226.         MOV     SS,CS:TmpSS                     ;Put stack at top
  227.         MOV     SP,0FFFEh                       ;  of memory
  228.         STI
  229.         DB      0EAh                            ;JMP FAR to code in PSP
  230. TmpIP   DW      0                               ;Patched in with offset
  231. TmpCS   DW      0                               ;Patched in with segment
  232. TmpSS   DW      0                               ;Temporary stack segment
  233.  
  234. ;-----------------------------------------------------------------------------
  235. ;Code executed in PSP
  236. CodeToRelocate:
  237.         INT     21h                             ;Call DOS EXEC
  238.         JNC     GoodLoad                        ;Check for error
  239.         INT     20h                             ;Error shouldn't happen,
  240.                                                 ; just halt if EXEC failed
  241. GoodLoad:
  242.         MOV     AX,CS                           ;Get base of program
  243.         MOV     DS,AX                           ;Initialize DS
  244.         MOV     ES,AX                           ;Initialize ES
  245.         CLI                                     ;Interrupts off
  246.         MOV     SS,DS:[0FEh]                    ;Initialize stack
  247.         MOV     SP,DS:[0FCh]
  248.         STI                                     ;Interrupts on again
  249.         DB      0EAh                            ;JMP FAR to start of code
  250. NewIP   DW      100h                            ;Patched in with start offset
  251. NewCS   DW      0                               ;Patched in with start segment
  252. NewSP   DW      0FFFEh                          ;Patched in with new SP
  253. NewSS   DW      0                               ;Patched in with new SS
  254.  
  255. Chain4  ENDP
  256.  
  257. Dummy   LABEL   BYTE
  258.  
  259. CODE    ENDS
  260.  
  261.         END
  262.